'''
国旗标准：https://openstd.samr.gov.cn/bzgk/std/std_list?p.p2=国旗
（一九四九年九月二十八日中国人民政治协商会议第一届全体会议主席团公布）
 国旗的形状、颜色两面相同，旗上五星两面相对。为便利计，本件仅以旗杆在左之一面为说之标准。对于旗杆在右之一 面，凡本件所称左均应改右，所称右均应改左。
（一） 旗面为红色，长方形，其长与高为三与二之比，旗面左上方缀黄色五角星五颗。一星较大，其外接圆直径为旗高十分之三，居左；四星较小，其外接圆直径为旗高十分之一，环拱于大星之右。旗杆套为白色。
（二） 五星之位置与画法如下：
甲 、为便于确定五星之位置，先将旗面对分为四个相等的长方形，将左上方之长方形上下划为十等分，左右划为十五等分。
乙 、大五角星的中心点，在该长方形上五下五、左五右十之处。
其画法为：以此点为圆心，以三等分为半径作一圆。在此圆周上，定出五个等距离的点，其一点须位于圆之正上方。然后将此五点中各相隔的两点相联，使各成一直线。此五直线所构成之外轮廓线，即为所需之大五角星。五角星之一个角尖正向上方。
丙 、四颗小五角星的中心点，第一点在该长方形上二下八、左十右五之处，第二点在上四下六、左十二右三之处，第三点在上七下三、左十二右三之处，第四点在上九下一、左十右五之处。其画法为：以以上四点为圆心，各以一等分为半径，分别作四个圆。在每个圆上各定出五个等距离的点，其中均须各有一点位于大五角星中心点与以上四个圆心的各联结线上。然后用构成大五角星的同样方法，构成小五角星。此四颗小五角星均各有一个角尖正对大五角星的中心点
（三） 国旗之通用尺度定为如下五种，各界酌情选用：
甲、长288公分，高192公分。
乙、长240公分，高160公分。
丙、长192公分，高128公分。
丁、长144公分，高96公分。
戊、长96公分，高64公分。
'''
import turtle
import math

# 设置国旗的尺寸（标准比例3:2）。
# 旗长用288的倍数（参考大小：288 x 192）
flag_length = 288 * 3
# 旗高用旗长计算，方便调整大小
flag_height = flag_length * 2 // 3

# 设置画布
screen = turtle.getscreen()
screen.title("红旗")
screen.setup(flag_length + 100, flag_height + 100)

# 设置画笔
pen = turtle.getpen()
pen.shape("turtle")
pen.speed(6) # 速度：0是最快、10是较快、6是正常、3是较慢、1是最慢

### 画红旗 开始 ###
pen.teleport(-flag_length/2, flag_height/2)
pen.color("red")
pen.begin_fill()
for _ in range(2):
    pen.forward(flag_length)
    pen.right(90)
    pen.forward(flag_height)
    pen.right(90)
pen.end_fill()
pen.color("black")
### 画红旗 结束 ###

step_length = flag_length / 2 / 15
# step_height = flag_height / 2 / 10
### 画参考线开始 ###

for i in range(10):
    pen.teleport(- flag_length / 2, i * step_length)
    pen.setheading(0)
    pen.forward(flag_length / 2)
    if i == 0:
        pen.forward(flag_length / 2)

for i in range(15):
    pen.teleport(- i * step_length, flag_height / 2)
    pen.setheading(-90)
    pen.forward(flag_height / 2)
    if i == 0:
        pen.forward(flag_height / 2)

### 画参考线结束 ###

### 找中心点开始 ###

# 一颗大五角星的中心点：
#   在该长方形上五下五、左五右十之处。
# 四颗小五角星的中心点：
#   第一点在上二下八、左十右五之处，
#   第二点在上四下六、左十二右三之处，
#   第三点在上七下三、左十二右三之处，
#   第四点在上九下一、左十右五之处
centers = [(0 - step_length * 10, step_length * 5), 
           (0 - step_length * 5, step_length * 8), 
           (0 - step_length * 3, step_length * 6), 
           (0 - step_length * 3, step_length * 3), 
           (0 - step_length * 5, step_length * 1)]
# 点出中心点
for x, y in centers:
    pen.teleport(x, y)
    pen.dot(10)

### 找中心点结束 ###

### 画外接圆开始 ###
def draw_circle(x, y, r):
    """ 
    绘制一个圆形。
    参数: x (float): 圆心的 x 坐标。 y (float): 圆心的 y 坐标。 r (float): 圆的半径。
    说明: 使用 turtle 模块的 pen 对象绘制圆形。 
    """
    pen.teleport(x, y - r)
    pen.setheading(0)
    pen.circle(r)

# 大五角星的外接圆半径（外接圆直径为旗高3/10）
radius_big = flag_height * 3 / 10 / 2
# 小五角星的外接圆半径（外接圆直径为旗高1/10）
radius_small = flag_height * 1 / 10 / 2
'''
x0, y0 = centers[0]
# pen.teleport(x0, y0 - radius_big)
# pen.setheading(0)
# pen.circle(radius_big)
draw_circle(x0, y0, radius_big)

for x, y in centers[1::]:
    # pen.teleport(x, y - radius_small)
    # pen.setheading(0)
    # pen.circle(radius_small)
    draw_circle(x, y, radius_small)
'''
# 将圆心坐标与半径存储到一个列表中
circles = [(0 - step_length * 10, step_length * 5, radius_big), 
           (0 - step_length * 5, step_length * 8, radius_small), 
           (0 - step_length * 3, step_length * 6, radius_small), 
           (0 - step_length * 3, step_length * 3, radius_small), 
           (0 - step_length * 5, step_length * 1, radius_small)]
for x, y, r in circles:
    draw_circle(x, y, r)

### 画外接圆结束 ###


### 算角度开始 ###

# 连线到大圆心
x0, y0 = centers[0]
for x, y, r in circles[1::]:
    pen.teleport(x, y)
    pen.goto(x0, y0)

# 计算两点的角度
def calculate_angle(x1, y1, x2, y2):
    """计算点(x1, y1)到点(x2, y2)的角度（其连线与x轴的夹角）"""
    # 计算水平和垂直差异
    dx = x2 - x1; dy = y2 - y1

    # x 相等时直接返回 90
    if dx == 0: return 90

    # 使用arctan函数计算角度，将弧度转换为角度
    return math.degrees(math.atan2(dy, dx))

### 算角度结束 ###

### 画五角星开始 ###

def draw_star(x = 0, y = 0, radius = 100, heading_angle = 90, color = "yellow"):

    pen.color(color)
    # pen.pencolor(color)
    # pen.fillcolor(color)

    # 调整方向
    pen.setheading(heading_angle) 

    # 根据半径计算边长
    side = radius * math.sin(math.radians(72)) / (1 + math.sin(math.radians(18)))

    pen.penup() # 提起笔
    pen.goto(x, y) # 到圆心
    pen.forward(radius) # 到圆边
    pen.right(180 - 18) # 掉头后便转18度
    # pen.pendown() # 不放下笔时不画边框，但会填充

    ## 开始画五角星
    pen.begin_fill() # 开始填充
    for _ in range(5):
        pen.forward(side)
        pen.left(72)
        pen.forward(side)
        pen.right(144)
    pen.end_fill() # 结束填充
    ## 结束画五角星

for x, y, r in circles:
    draw_star(x, y, r, calculate_angle(x, y, x0, y0))
### 画五角星结束 ###


# 收笔
pen.hideturtle()
# 持续显示
screen.mainloop()